import { ref, computed, watch } from 'vue'

interface ImageOptimizationOptions {
    src: string
    quality?: number
    webp?: boolean
    placeholder?: string
    maxRetries?: number
    cacheTime?: number
}

// 图片缓存管理
class ImageCache {
    private cache = new Map<string, { url: string; timestamp: number; blob?: Blob }>()
    private maxSize = 50 // 最大缓存数量

    set(key: string, url: string, cacheTime: number, blob?: Blob) {
        // 清理过期缓存
        this.cleanup()

        // 如果缓存已满，删除最旧的
        if (this.cache.size >= this.maxSize) {
            const oldestKey = Array.from(this.cache.keys())[0]
            this.cache.delete(oldestKey)
        }

        this.cache.set(key, {
            url,
            timestamp: Date.now() + cacheTime * 1000,
            blob
        })
    }

    get(key: string): string | null {
        const item = this.cache.get(key)
        if (!item) return null

        // 检查是否过期
        if (Date.now() > item.timestamp) {
            this.cache.delete(key)
            return null
        }

        return item.url
    }

    private cleanup() {
        const now = Date.now()
        for (const [key, item] of this.cache.entries()) {
            if (now > item.timestamp) {
                this.cache.delete(key)
            }
        }
    }

    clear() {
        this.cache.clear()
    }
}

const imageCache = new ImageCache()

// 图片格式检测
const getSupportedFormat = () => {
    // #ifdef H5
    const canvas = document.createElement('canvas')
    const webpSupported = canvas.toDataURL('image/webp').indexOf('data:image/webp') === 0
    return webpSupported ? 'webp' : 'jpg'
    // #endif

    // #ifdef MP-WEIXIN
    return 'jpg' // 微信小程序不支持webp
    // #endif

    // #ifdef APP-PLUS
    return 'webp' // App支持webp
    // #endif

    return 'jpg'
}

// 生成优化后的图片URL
const generateOptimizedUrl = (src: string, options: ImageOptimizationOptions): string => {
    if (!src) return ''

    // 如果是本地图片，直接返回
    if (src.startsWith('/static/') || src.startsWith('data:')) {
        return src
    }

    // 如果已经是完整URL，进行参数优化
    if (src.startsWith('http')) {
        const url = new URL(src)

        // 添加质量参数
        if (options.quality && options.quality < 100) {
            url.searchParams.set('quality', options.quality.toString())
        }

        // 添加格式参数
        if (options.webp && getSupportedFormat() === 'webp') {
            url.searchParams.set('format', 'webp')
        }

        return url.toString()
    }

    // 相对路径处理
    const baseUrl = import.meta.env.VITE_APP_BASE_URL || ''
    // 确保 baseUrl 和 src 之间有正确的斜杠
    const separator = baseUrl.endsWith('/') || src.startsWith('/') ? '' : '/'
    let optimizedUrl = baseUrl + separator + src

    // 添加优化参数
    const params = new URLSearchParams()
    if (options.quality && options.quality < 100) {
        params.set('quality', options.quality.toString())
    }
    if (options.webp && getSupportedFormat() === 'webp') {
        params.set('format', 'webp')
    }

    if (params.toString()) {
        optimizedUrl += (optimizedUrl.includes('?') ? '&' : '?') + params.toString()
    }

    return optimizedUrl
}

export function useImageOptimization(options: ImageOptimizationOptions) {
    const loading = ref(true)
    const hasError = ref(false)
    const loadProgress = ref(0)
    const retryCount = ref(0)

    // 生成缓存key
    const cacheKey = computed(() => {
        return `${options.src}_${options.quality}_${options.webp}`
    })

    // 优化后的图片URL
    const optimizedSrc = computed(() => {
        // 先检查缓存
        const cached = imageCache.get(cacheKey.value)
        if (cached) {
            return cached
        }

        // 生成优化URL
        const optimized = generateOptimizedUrl(options.src, options)

        // 缓存结果
        if (optimized && options.cacheTime) {
            imageCache.set(cacheKey.value, optimized, options.cacheTime)
        }

        return optimized
    })

    // 预加载图片
    const preloadImage = async (): Promise<boolean> => {
        return new Promise((resolve) => {
            if (!optimizedSrc.value) {
                resolve(false)
                return
            }

            loading.value = true
            hasError.value = false
            loadProgress.value = 0

            // #ifdef H5
            const img = new Image()
            img.onload = () => {
                loading.value = false
                loadProgress.value = 100
                resolve(true)
            }
            img.onerror = () => {
                loading.value = false
                hasError.value = true
                resolve(false)
            }
            img.src = optimizedSrc.value
            // #endif

            // #ifdef MP-WEIXIN || APP-PLUS
            uni.getImageInfo({
                src: optimizedSrc.value,
                success: () => {
                    loading.value = false
                    loadProgress.value = 100
                    resolve(true)
                },
                fail: () => {
                    loading.value = false
                    hasError.value = true
                    resolve(false)
                }
            })
            // #endif
        })
    }

    // 重试加载
    const retryLoad = async () => {
        if (retryCount.value >= (options.maxRetries || 3)) {
            return false
        }

        retryCount.value++
        hasError.value = false

        return await preloadImage()
    }

    // 监听src变化，重置状态
    watch(
        () => options.src,
        () => {
            loading.value = true
            hasError.value = false
            loadProgress.value = 0
            retryCount.value = 0
        }
    )

    return {
        optimizedSrc,
        loading,
        hasError,
        loadProgress,
        retryCount,
        preloadImage,
        retryLoad
    }
}

// 批量预加载图片
export function useBatchImagePreload() {
    const preloadQueue = ref<string[]>([])
    const preloadedImages = ref<Set<string>>(new Set())
    const isPreloading = ref(false)

    const addToPreloadQueue = (urls: string | string[]) => {
        const urlArray = Array.isArray(urls) ? urls : [urls]
        preloadQueue.value.push(...urlArray.filter((url) => !preloadedImages.value.has(url)))
    }

    const startPreload = async (concurrency = 3) => {
        if (isPreloading.value || preloadQueue.value.length === 0) return

        isPreloading.value = true

        const processQueue = async () => {
            const promises: Promise<void>[] = []

            for (let i = 0; i < Math.min(concurrency, preloadQueue.value.length); i++) {
                const url = preloadQueue.value.shift()
                if (!url) continue

                promises.push(
                    new Promise<void>((resolve) => {
                        // #ifdef H5
                        const img = new Image()
                        img.onload = img.onerror = () => {
                            preloadedImages.value.add(url)
                            resolve()
                        }
                        img.src = url
                        // #endif

                        // #ifdef MP-WEIXIN || APP-PLUS
                        uni.getImageInfo({
                            src: url,
                            success: () => {
                                preloadedImages.value.add(url)
                                resolve()
                            },
                            fail: () => {
                                preloadedImages.value.add(url)
                                resolve()
                            }
                        })
                        // #endif
                    })
                )
            }

            await Promise.all(promises)

            if (preloadQueue.value.length > 0) {
                await processQueue()
            }
        }

        await processQueue()
        isPreloading.value = false
    }

    return {
        addToPreloadQueue,
        startPreload,
        preloadedImages: computed(() => preloadedImages.value),
        isPreloading: computed(() => isPreloading.value)
    }
}
